package falcon.server.processor;

import falcon.common.Errno;
import falcon.common.Log;
import falcon.protocol.Packet;
import falcon.protocol.PacketFactory;
import falcon.protocol.impl.AckPacket;
import falcon.protocol.impl.BashPacket;
import falcon.protocol.impl.FlowPacket;
import falcon.protocol.impl.FuncPacket;
import falcon.protocol.impl.HostPacket;
import falcon.protocol.impl.SysPacket;
import falcon.server.FalconByteBufHandler;
import falcon.server.FalconProManager;

public final class FalconProcessor implements Runnable {

	public FalconProcessor() {
		
	}

	@Override
	public void run() {
		try {
			while (true) {
				long sleepTime;
				try {
					FalconProManager.Req req = m_manager.getReq();
					sleepTime = process(req);
				} catch (Exception e) {
					sleepTime = 30000L;
					Log.log(e, "");
				}
				Thread.sleep(sleepTime);
			}
		} catch (Exception e) {
			
		}
	}
	
	public void bind(FalconProManager manager) {
		m_manager = manager;
	}

	private long process(FalconProManager.Req req) {
		if (req == null) {
			return 1000L;
		}
		int id = req.id;
		Packet packet = req.packet;
		int cmd = packet.getCmd();
		FalconByteBufHandler handler = req.handler;
		try {
			if (!isAuth(cmd, packet, handler)) {
				req.errno = Errno.VERIF_NOT_LOGIN;
				req.desc = "未登陆";
			} else if (cmd == PacketFactory.SYS) {
				processSys((SysPacket) packet, req);
			} else if (cmd == PacketFactory.BASH) {
				processBash((BashPacket) packet, req);
			} else if (cmd == PacketFactory.FUNC) {
				processFunc((FuncPacket) packet, req);
			} else if (cmd == PacketFactory.FLOW) {
				processFlow((FlowPacket) packet, req);
			} else if (cmd == PacketFactory.HOST) {
				processHost((HostPacket) packet, req);
			} else {
				req.errno = Errno.PROTOCOL_CMD_ERROR;
				req.desc = String.format("服务端不支持的命令;cmd=%d", cmd);
			}
		} catch (Exception e) {
			req.errno = Errno.COM_CATCH_EXCEPTION;
			req.desc = "服务端异常";
			Log.log(e, "process failure;id=%d", id);
		}
		processAck(id, req.errno, req.desc, handler);
		return 0L;
	}
	
	private void processAck(int id, int errno, String desc, FalconByteBufHandler handler) {
		AckPacket ackPacket = (AckPacket) PacketFactory.create(PacketFactory.ACK, 0);
		ackPacket.id = id;
		ackPacket.errno = errno;
		ackPacket.desc = desc;
		boolean close = false;
		if (errno >= Errno.VERIF_LOGOUT && errno <= 649) {
			close = true;
			if (errno == Errno.VERIF_LOGOUT) {
				ackPacket.errno = Errno.SUCCESS;
			}
		}
		handler.channelWrite(ackPacket, close);
	}
	
	private void processSys(SysPacket packet, FalconProManager.Req req) {
		int action = packet.action;
		String[] pa = packet.parameter.split("\n");
		if (action == SysPacket.Action.LOGIN) {
			FalconSysProcessor.processLogin(m_manager, req, pa);
		} else if (action == SysPacket.Action.LOGOUT) {
			FalconSysProcessor.processLogout(m_manager, req, pa);
		} else {
			req.errno = Errno.PROTOCOL_ACTION_ERROR;
			req.desc = String.format("不支持的操作;action=%d", action);
		}
	}
	
	private void processBash(BashPacket packet, FalconProManager.Req req) {
		String[] pa = new String[5];
		pa[0] = packet.cmd;
		pa[1] = packet.host;
		pa[2] = Integer.toString(packet.port);
		pa[3] = packet.user;
		pa[4] = "";// password
		FalconBashProcessor.processExec(m_manager, req, pa);
	}
	
	private void processFunc(FuncPacket packet, FalconProManager.Req req) {
		
	}
	
	private void processFlow(FlowPacket packet, FalconProManager.Req req) {
		int action = packet.action;
		String name = packet.name;
		String parameter = packet.parameter;
		String[] pa = new String[2];
		pa[0] = name;
		pa[1] = parameter;
		if (action == FlowPacket.Action.EXECUTE) {
			FalconFlowProcessor.processExec(m_manager, req, pa);
		} else {
			req.errno = Errno.PROTOCOL_ACTION_ERROR;
			req.desc = String.format("不支持的操作;action=%d", action);
		}
	}
	
	private void processHost(HostPacket packet, FalconProManager.Req req) {
		int action = packet.action;
		String cipher = packet.cipher;
		String[] pa = packet.parameter.split("\n");
		pa[0] = cipher;
		
		if (action == HostPacket.Action.ADD) {
			FalconHostProcessor.processAdd(m_manager, req, pa);
		} else if (action == HostPacket.Action.REMOVE) {
			FalconHostProcessor.processRemove(m_manager, req, pa);
		} else {
			req.errno = Errno.PROTOCOL_ACTION_ERROR;
			req.desc = String.format("不支持的操作;action=%d", action);
		}
	}
	
	private boolean isAuth(int cmd, Packet packet, FalconByteBufHandler handler) {
		if (cmd != PacketFactory.SYS) {
			return handler.isLogin();
		}
		SysPacket p = (SysPacket) packet;
		if (p.action != SysPacket.Action.LOGIN) {
			return handler.isLogin();
		}
		return true;
	}
	
	private FalconProManager m_manager;
}
